package player_mananger

import (
	"fmt"
	"log"
	"my-gameserver-go/core/mynet/conn"
	mynet_handler "my-gameserver-go/core/mynet/handler"
	"my-gameserver-go/core/mynet/handler/abs"
	"my-gameserver-go/logic/consts"
	enums_ctxstate "my-gameserver-go/logic/consts/enums"
	"my-gameserver-go/logic/db"
	"my-gameserver-go/logic/message"
	persis "my-gameserver-go/logic/persistenceObj"
	"my-gameserver-go/proto/s2c"
	"net"
	"reflect"
	"time"
)

type Manager struct {
	connPlayerMap     map[net.Conn]*persis.Player //
	onlinePlayerMap   map[int64]*persis.Player    //
	PlayerRoutinePool []chan mynet_handler.BaseHandler
}

var InsPlayerManager *Manager

//初始化方式
func init() {
	InsPlayerManager = &Manager{
		connPlayerMap:     make(map[net.Conn]*persis.Player),
		onlinePlayerMap:   make(map[int64]*persis.Player),
		PlayerRoutinePool: make([]chan mynet_handler.BaseHandler, consts.PlayerRoutineNum),
	}
}

func (playerManager *Manager) GetPlayerByConn(conn net.Conn) (*persis.Player, bool) {
	player, ok := playerManager.connPlayerMap[conn]
	return player, ok
}

func (playerManager *Manager) RegisterPlayer(player *persis.Player) {
	playerManager.connPlayerMap[player.Conn.Conn] = player
	playerManager.onlinePlayerMap[player.PlayerId] = player
}

func (playerManager *Manager) PlayerInit(player *persis.Player, gameConn *conn.GameConnection) {
	//初始化玩家
	gameConn.SetAttr(consts.ConnPlayerState, enums_ctxstate.NORMAL)
	//player routine执行init玩家
	player.Conn = gameConn
	//注册玩家
	playerManager.RegisterPlayer(player)
	//状态都设置好了 save一下
	db.PlayerAccess.Save(player)
	s2cLogin := &s2c.S2CLoginMessage{ServerTime: int32(time.Now().Second())}
	message.InsMessageManager.PlayerSend(gameConn, s2c.S2CLoginMessage_eMsgID, s2cLogin)
}
func (playerManager *Manager) PlayerOut(player *persis.Player) {
	player.Conn.ClearAttr(consts.ChannelInfo)
	log.Println(consts.LOG_LOGIN_PREFIX + "conn disconnected,player in login out")
}
func (playerManager *Manager) InnerHandlerSend(routineChanIndex int32, innerHandler abs.GenericInnerHandler) {
	t := reflect.TypeOf(innerHandler)
	fmt.Println(t)
	pChan := playerManager.PlayerRoutinePool[routineChanIndex]
	idleTimeout := time.NewTimer(5 * time.Millisecond)
	select {
	case <-idleTimeout.C:
		fmt.Println("send InnerSend timeout")
	case pChan <- innerHandler:
		fmt.Println("c.InnerSend write success")
	}
}

// ProtoMsgSend proto消息使用的handler
func (playerManager *Manager) ProtoHandlerSend(routineChanIndex int32, baseHandler mynet_handler.BaseHandler) {
	t := reflect.TypeOf(baseHandler)
	fmt.Println(t)
	pChan := playerManager.PlayerRoutinePool[routineChanIndex]
	idleTimeout := time.NewTimer(5 * time.Millisecond)
	select {
	case <-idleTimeout.C:
		fmt.Println("send ProtoMsgSend timeout")
	case pChan <- baseHandler:
		fmt.Println("c.ProtoMsgSend write success")
	}
}
